home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SGI Developer Toolbox 6.1
/
SGI Developer Toolbox 6.1 - Disc 4.iso
/
src
/
haeberli
/
libgutil
/
corprt3.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-08-01
|
6KB
|
325 lines
/*
* Copyright 1991, 1992, 1993, 1994, Silicon Graphics, Inc.
* All Rights Reserved.
*
* This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
* the contents of this file may not be disclosed to third parties, copied or
* duplicated in any form, in whole or in part, without the prior written
* permission of Silicon Graphics, Inc.
*
* RESTRICTED RIGHTS LEGEND:
* Use, duplication or disclosure by the Government is subject to restrictions
* as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
* and Computer Software clause at DFARS 252.227-7013, and/or in similar or
* successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
* rights reserved under the Copyright Laws of the United States.
*/
/*
* corimg3 -
* This contains generic corimg3 and sproof3 stuff. This color
* Correction technique is for single angle color screening.
*
* Paul Haeberli - 1989
*
* use corone3(r,g,b,cr,cg,cb)
* and sproof3(r,g,b,cr,cg,cb) in the simplest case.
*
*
* exports
*
void corrow3(rbuf,gbuf,bbuf,n)
void corone3(r,g,b,cr,cg,cb)
void sproofrow3(rbuf,gbuf,bbuf,n)
void sproof3(r,g,b,sr,sg,sb)
*
*/
#include "stdio.h"
#include "math.h"
#include "vect.h"
#include "swop.h"
float flerp();
static void setprinter();
void corone3();
void sproof3();
#define EPSILON (0.0001)
#define NRAYS (6*TABSIZE)
#define TABSIZE (6*256)
static vect tabc, tabm, taby;
static vect tabr, tabg, tabb;
static float tab[TABSIZE][3];
static float cmin[TABSIZE];
static float cmax[TABSIZE];
static int corfirsted;
static int spfirsted;
static maketable()
{
float h, s, v;
float r, g, b;
float sr, sg, sb;
float min, max, chroma;
int i, tabi;
setprinter();
for(i=0; i<TABSIZE; i++)
tab[i][0] = -1000.0;
for(i=0; i<NRAYS; i++) {
h = i/(NRAYS-1.0);
hsv_to_rgb(h,1.0,1.0,&r,&g,&b);
sproof3(r,g,b,&sr,&sg,&sb);
rgb_to_hsv(sr,sg,sb,&h,&s,&v);
min = max = sr;
if(sg<min)
min = sg;
if(sg>max)
max = sg;
if(sb<min)
min = sb;
if(sb>max)
max = sb;
tabi = TABSIZE*h;
if(tabi == TABSIZE)
tabi = 0;
cmin[tabi] = min;
cmax[tabi] = max;
tab[tabi][0] = r;
tab[tabi][1] = g;
tab[tabi][2] = b;
}
for(i=0; i<TABSIZE; i++) {
if(tab[i][0]<=-1000.0) {
fprintf(stderr,"corimg3: bad\n");
}
}
}
static float clamp(f)
float f;
{
if(f<0.0)
return 0.0;
else if(f>1.0)
return 1.0;
else
return f;
}
void corrow3(rbuf,gbuf,bbuf,n)
short *rbuf;
short *gbuf;
short *bbuf;
int n;
{
float cr, cg, cb;
short lr, lg, lb;
short ir, ig, ib;
lr = lg = lb = -1000;
while(n--) {
if((*rbuf != lr) || (*gbuf != lg) || (*bbuf != lb)) {
lr = *rbuf;
lg = *gbuf;
lb = *bbuf;
corone3(lr/255.0,lg/255.0,lb/255.0,&cr,&cg,&cb);
ir = cr*255.0+0.5;
ig = cg*255.0+0.5;
ib = cb*255.0+0.5;
}
*rbuf++ = ir;
*gbuf++ = ig;
*bbuf++ = ib;
}
}
void corone3(r,g,b,cr,cg,cb)
float r, g, b;
float *cr, *cg, *cb;
{
float min, max;
float h, s, v;
float tr, tg, tb;
float chroma, mag;
float white, cscale;
int tabi;
float tabmax, tabmin;
if(!corfirsted) {
maketable();
corfirsted = 1;
}
min = max = r;
if(g<min)
min = g;
if(g>max)
max = g;
if(b<min)
min = b;
if(b>max)
max = b;
chroma = max-min;
if(chroma<EPSILON) {
*cr = r;
*cg = g;
*cb = b;
} else {
white = min/max;
rgb_to_hsv(r,g,b,&h,&s,&v);
tabi = TABSIZE*h;
if(tabi == TABSIZE)
tabi = 0;
tabmax = cmax[tabi];
tr = tab[tabi][0]/tabmax;
tg = tab[tabi][1]/tabmax;
tb = tab[tabi][2]/tabmax;
tr = flerp(tr,1.0,white);
tg = flerp(tg,1.0,white);
tb = flerp(tb,1.0,white);
*cr = clamp(max*tr);
*cg = clamp(max*tg);
*cb = clamp(max*tb);
}
}
void sproofrow3(rbuf,gbuf,bbuf,n)
unsigned short *rbuf, *gbuf, *bbuf;
int n;
{
float cr, cg, cb;
short lr, lg, lb;
short ir, ig, ib;
lr = lg = lb = -1000;
while(n--) {
if((*rbuf != lr) || (*gbuf != lg) || (*bbuf != lb)) {
lr = *rbuf;
lg = *gbuf;
lb = *bbuf;
sproof3(lr/255.0,lg/255.0,lb/255.0,&cr,&cg,&cb);
ir = cr*255.0+0.5;
ig = cg*255.0+0.5;
ib = cb*255.0+0.5;
}
*rbuf++ = ir;
*gbuf++ = ig;
*bbuf++ = ib;
}
}
void sproof3(r,g,b,sr,sg,sb)
float r, g, b;
float *sr, *sg, *sb;
{
float fc, fm, fy;
float min, max;
float white, chroma, p;
float val;
int bits;
vect col;
if(!spfirsted) {
setprinter();
spfirsted = 1;
}
fc = 1.0-r;
fm = 1.0-g;
fy = 1.0-b;
bits = 0;
max = min = fc;
if(fc>fm) {
if(fc>fy) {
bits |= (1<<0);
max = fc;
} else {
bits |= (1<<2);
max = fy;
}
if(fm<fy) {
bits |= (1<<1);
min = fm;
} else {
bits |= (1<<2);
min = fy;
}
} else {
if(fm>fy) {
bits |= (1<<1);
max = fm;
} else {
bits |= (1<<2);
max = fy;
}
if(fc<fy) {
bits |= (1<<0);
min = fc;
} else {
bits |= (1<<2);
min = fy;
}
}
white = 1.0-max;
chroma = max-min;
if(chroma<EPSILON) {
val = 1.0-min;
*sr = val;
*sg = val;
*sb = val;
} else {
if((bits&(1<<0)) == 0) {
p = (fc-min)/chroma;
if(fm == max)
vlerp(&tabm,&tabb,&col,p);
else
vlerp(&taby,&tabg,&col,p);
} else if((bits&(1<<1)) == 0) {
p = (fm-min)/chroma;
if(fy == max) {
vlerp(&taby,&tabr,&col,p);
} else {
vlerp(&tabc,&tabb,&col,p);
}
} else if((bits&(1<<2)) == 0) {
p = (fy-min)/chroma;
if(fc == max)
vlerp(&tabc,&tabg,&col,p);
else
vlerp(&tabm,&tabr,&col,p);
} else {
fprintf(stderr,"sproof3: bad poop\n");
exit(1);
}
vscale(&col,chroma);
col.x += white;
col.y += white;
col.z += white;
*sr = col.x;
*sg = col.y;
*sb = col.z;
}
}
static void setprinter()
{
tabc.x = ct3[CYA][0];
tabc.y = ct3[CYA][1];
tabc.z = ct3[CYA][2];
tabm.x = ct3[MAG][0];
tabm.y = ct3[MAG][1];
tabm.z = ct3[MAG][2];
taby.x = ct3[YEL][0];
taby.y = ct3[YEL][1];
taby.z = ct3[YEL][2];
tabb.x = ct3[BLU][0];
tabb.y = ct3[BLU][1];
tabb.z = ct3[BLU][2];
tabg.x = ct3[GRE][0];
tabg.y = ct3[GRE][1];
tabg.z = ct3[GRE][2];
tabr.x = ct3[RED][0];
tabr.y = ct3[RED][1];
tabr.z = ct3[RED][2];
}